package com.wstuo.common.security.utils;

import com.wstuo.common.security.dao.IResourceDAO;
import com.wstuo.common.security.entity.Resource;
import com.wstuo.common.security.entity.Role;
import com.wstuo.common.security.service.EnduserCompetence;
import com.wstuo.common.security.service.IRoleService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

/**
 * ResourceSecurityMetaDataSource
 * 
 * @author QXY
 * 
 */
public class ResourceSecurityMetaDataSource implements FilterInvocationSecurityMetadataSource {
	@Autowired
	private IResourceDAO resourceDAO;

	@Autowired
	private EnduserCompetence enduserCompetence;

	// private UrlMatcher urlMatcher = new AntUrlPathMatcher();

	/**
	 * Retrieves the list of config attributes (ROLE CODE here) by the given secureObject (Request Url here)
	 * 
	 * @param secureObject
	 * @return Collection<ConfigAttribute>
	 */
	@Transactional
	public Collection<ConfigAttribute> getAttributes(Object secureObject) {
		Collection<ConfigAttribute> configAttributes = null;
		String requestUrl = ((FilterInvocation) secureObject).getRequestUrl();
		// Resource resource = resourceDAO.findUniqueBy("resUrl", requestUrl);
		Resource resource = resourceDAO.findByResUrl(requestUrl);

		if (resource != null) {
			Set<Role> roles = resource.getRoles();

			configAttributes = new ArrayList<ConfigAttribute>();
			for (Role role : roles) {
				if (role.getRoleState()) {// 未被禁用的
					if (IRoleService.ROLE_ENDUSER.equals(role.getRoleCode())) {
						if (enduserCompetence.getCompetences().contains(requestUrl)) {
							ConfigAttribute configAttribute = new SecurityConfig(role.getRoleCode());
							configAttributes.add(configAttribute);
						}
					} else {
						ConfigAttribute configAttribute = new SecurityConfig(role.getRoleCode());
						configAttributes.add(configAttribute);
					}
				}
			}
		}

		return configAttributes;
	}

	/**
	 * getAllConfigAttributes
	 * 
	 * @return Collection<ConfigAttribute>
	 */
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		// TODO Auto-generated method stub
		Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();

		configAttributes.add(new SecurityConfig("ROLE_ANONYMOUS"));
		configAttributes.add(new SecurityConfig("ROLE_ADMIN"));
		configAttributes.add(new SecurityConfig("ROLE_USER"));

		return configAttributes;
	}

	/**
	 * supports
	 * 
	 * @param cls
	 * @return boolean
	 */
	public boolean supports(Class<?> cls) {
		return (cls.equals(FilterInvocation.class));
	}
}
